home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / dsp4tool / dlibcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-14  |  8.5 KB  |  316 lines

  1. /*  DLIBCMD.C -- Commands for DSP CARD 4 ROM library
  2.  *
  3.  *  Copyright (C) by Alef Null 1992, 1993, 1994
  4.  *  Author(s): Jarkko Vuori, OH2LNS
  5.  *  Modification(s):
  6.  */
  7.  
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <time.h>
  13. #include <dos.h>
  14. #include <sys\types.h>
  15. #include <sys\stat.h>
  16. #include "utils.h"
  17. #include "dlib.h"
  18.  
  19. #define LOAD_ADDRESS 0x0000
  20. #define BOOT_ADDRESS 0xC000
  21. #define BOOT_LEN     512
  22. #define BOOT_END     0xD400
  23. #define ROM_BASE     0x8000
  24. #define ROM_LEN      32768
  25. #define DIR_LEN      (DIR_ENTRIES*sizeof(ROMDIR))
  26. #define CHECK_LEN    sizeof(unsigned short)
  27.  
  28. struct {
  29.     ROMDIR       dir[DIR_ENTRIES];
  30.     unsigned char  data[ROM_LEN-DIR_LEN-CHECK_LEN];
  31.     unsigned short check;
  32. } rom;
  33.  
  34.  
  35. /*
  36.  * Read ROM image file and check that it is a valid one
  37.  */
  38. static Bool loadROMandCheckValidity(FILE *fp) {
  39.     struct stat  statBuf;
  40.  
  41.     fstat(fileno(fp), &statBuf);
  42.     if (statBuf.st_size) {
  43.     /* check ROM library file validity */
  44.     fread(&rom, ROM_LEN, 1, fp);
  45.     if (statBuf.st_size != ROM_LEN || rom.dir[0].adr != CHECK_ID) {
  46.         fprintf(stderr, "illegal ROM library file\n");
  47.         return (False);
  48.     }
  49.     if (crc((unsigned char *)&rom, sizeof(rom)) != 0xf0b8) {
  50.         fprintf(stderr, "bad CRC in ROM library file\n");
  51.         return (False);
  52.     }
  53.     }
  54.  
  55.     return (True);
  56. }
  57.  
  58.  
  59. /*
  60.  * Write ROM image back to the file
  61.  */
  62. static Bool storeROM(FILE *fp) {
  63.     rom.check = ~crc((unsigned char *)&rom, sizeof(rom)-CHECK_LEN);
  64.     fseek(fp, 0L, SEEK_SET); fwrite(&rom, ROM_LEN, 1, fp);
  65.  
  66.     return (True);
  67. }
  68.  
  69.  
  70. /*
  71.  *  Return date string from the directory entry
  72.  */
  73. static char *dateStr(ROMDIR *entry) {
  74.     struct {
  75.     int   co_date;        // date format
  76.     char  co_curr[5];   // currency symbol
  77.     char  co_thsep[2];  // thousands separator
  78.     char  co_desep[2];  // decimal separator
  79.     char  co_dtsep[2];  // date separator
  80.     char  co_tmsep[2];  // time separator
  81.     char  co_currstyle; // currency style
  82.     char  co_digits;    // significant digits in currency
  83.     char  co_time;        // time format
  84.     long  co_case;        // case map
  85.     char  co_dasep[2];  // data separator
  86.     char  co_fill[10];  // filler
  87.     } country_info;
  88.     static char result[10+1];
  89.  
  90.     /* first obtain the current output format */
  91.     bdos(0x38, (unsigned)&country_info, 0x00);
  92.  
  93.     /* finally formulate date using correct format */
  94.     switch (country_info.co_date) {
  95.     case 0: // USA
  96.     sprintf(result, "%02d%s%02d%s%04d", entry->date.month+1, country_info.co_dtsep, entry->date.day, country_info.co_dtsep, entry->date.year+1900);
  97.     break;
  98.  
  99.     case 1: // Europe
  100.     default:
  101.     sprintf(result, "%02d%s%02d%s%04d", entry->date.day, country_info.co_dtsep, entry->date.month+1, country_info.co_dtsep, entry->date.year+1900);
  102.     break;
  103.  
  104.     case 2: // Japan
  105.     sprintf(result, "%04d%s%02d%s%02d", entry->date.year+1900, country_info.co_dtsep, entry->date.month+1, country_info.co_dtsep, entry->date.day);
  106.     break;
  107.     }
  108.  
  109.     return (result);
  110. }
  111.  
  112.  
  113. /*
  114.  * Update ROM directory entry
  115.  */
  116. static void updateDirEntry(ROMDIR *entry, unsigned address, unsigned words, char *comment, FILE *fp) {
  117.     struct stat  statBuf;
  118.     struct tm    *mt;
  119.  
  120.     /* update pointers to binary data */
  121.     entry->adr = address;
  122.     entry->len = words;
  123.  
  124.     /* copy the name of the binary image */
  125.     memcpy(entry->description, comment, DESC_LEN);
  126.  
  127.     /* and finally form the date field */
  128.     fstat(fileno(fp), &statBuf);
  129.     mt = localtime(&statBuf.st_mtime);
  130.     entry->date.year  = mt->tm_year;
  131.     entry->date.month = mt->tm_mon;
  132.     entry->date.day   = mt->tm_mday;
  133. }
  134.  
  135.  
  136. /* data aggregate for setBlock parameters */
  137. static struct {
  138.     Bool       fBoot;
  139.     unsigned       words;
  140.     unsigned char *pb;
  141.     unsigned char *lowaddress;
  142.     unsigned char *highaddress;
  143. } setBlockData;
  144.  
  145.  
  146. /*
  147.  * load one block of memory to ROM
  148.  */
  149. static Bool setBlock(BLKHEADER *pHeader, long huge *data) {
  150.     unsigned char *pbOld;
  151.  
  152.     if (setBlockData.fBoot) {
  153.     /* only P memory load allowed in first 512 words of boot program */
  154.     if (pHeader->space != p) {
  155.         fprintf(stderr, "only P memory loadable\n");
  156.         return (False);
  157.     }
  158.  
  159.     /* switch to internal loader mode if first 512 words of boot program loaded */
  160.     if (pHeader->address < BOOT_LEN)
  161.         setBlockData.pb    = &rom.data[BOOT_ADDRESS+3*pHeader->address-ROM_BASE]-DIR_LEN;
  162.     else {
  163.         setBlockData.pb    = &rom.data[BOOT_ADDRESS+3*BOOT_LEN-ROM_BASE]-DIR_LEN;
  164.         setBlockData.fBoot = False;
  165.     }
  166.     }
  167.  
  168.     /* check memory limits */
  169.     if (setBlockData.pb+sizeof(BLKHEADER)+3*pHeader->len > setBlockData.highaddress) {
  170.     fprintf(stderr, "too big load image (max. size is %d words)\n", (setBlockData.highaddress-setBlockData.lowaddress)/3);
  171.     return (False);
  172.     }
  173.  
  174.     pbOld = setBlockData.pb;
  175.     if (!setBlockData.fBoot) {
  176.     unsigned char *p;
  177.  
  178.     /* store header */
  179.     for (p = (unsigned char *)pHeader; p < (unsigned char *)pHeader+sizeof(BLKHEADER); p++)
  180.         *setBlockData.pb++ = *p;
  181.     }
  182.  
  183.     /* store 24-bit word to three consecutive ROM locations */
  184.     for (;pHeader->len; pHeader->len--) {
  185.     *setBlockData.pb++ = (unsigned char)*data;
  186.     *setBlockData.pb++ = (unsigned char)(*data >> 8);
  187.     *setBlockData.pb++ = (unsigned char)(*data++ >> 16);
  188.     }
  189.  
  190.     setBlockData.words += setBlockData.pb - pbOld;
  191.  
  192.     return (True);
  193. }
  194.  
  195.  
  196. /*
  197.  * Load linker output file to the ROM image
  198.  */
  199. static unsigned loadLinkerToImage(FILE *fp, Bool fBoot, unsigned lowaddress, unsigned highaddress) {
  200.     static BLKHEADER termBlk = { p, 0, 0 };
  201.  
  202.     setBlockData.pb         = &rom.data[lowaddress-ROM_BASE]-DIR_LEN;
  203.     setBlockData.words         = 0;
  204.     setBlockData.fBoot         = fBoot;
  205.     setBlockData.lowaddress  = &rom.data[lowaddress-ROM_BASE]-DIR_LEN;
  206.     setBlockData.highaddress = &rom.data[highaddress-ROM_BASE]-DIR_LEN;
  207.     ReadBlocks(fp, setBlock);
  208.  
  209.     /* set program terminator block */
  210.     setBlock(&termBlk, NULL);
  211.  
  212.     return (setBlockData.words);
  213. }
  214.  
  215.  
  216. /*
  217.  * Give first free address location
  218.  */
  219. static unsigned freeLocation(void) {
  220.     ROMDIR   *p;
  221.     unsigned  top;
  222.  
  223.     top = DIR_LEN+ROM_BASE;
  224.     for (p = &rom.dir[1]; p < &rom.dir[DIR_ENTRIES]; p++)
  225.     if (p->len)
  226.         top = max(top, p->adr + p->len);
  227.  
  228.     return (top);
  229. }
  230.  
  231.  
  232. Bool cdecl autoboot(FILE *files[], int numArg) {
  233.     if (!loadROMandCheckValidity(files[0]))
  234.     return (False);
  235.  
  236.     rom.dir[0].len = numArg;
  237.     storeROM(files[0]);
  238.  
  239.     return (True);
  240. }
  241.  
  242.  
  243. Bool cdecl replace(FILE *files[], int numArg, char *comment) {
  244.     unsigned startAddress, words;
  245.  
  246.     if (numArg <= 0 || numArg >= DIR_ENTRIES) {
  247.     fprintf(stderr, "illegal program number\n");
  248.     return (False);
  249.     }
  250.  
  251.     if (!loadROMandCheckValidity(files[0]))
  252.     return (False);
  253.  
  254.     startAddress = freeLocation();
  255.     if ((words = loadLinkerToImage(files[1], False, startAddress, BOOT_ADDRESS)) != 0) {
  256.     updateDirEntry(&rom.dir[numArg], startAddress, words, comment, files[1]);
  257.     storeROM(files[0]);
  258.     } else
  259.     return (False);
  260.  
  261.     return (True);
  262. }
  263.  
  264.  
  265. Bool cdecl bootimage(FILE *files[], int numArg, char *comment) {
  266.     struct stat statBuf;
  267.     unsigned    words;
  268.  
  269.     fstat(fileno(files[0]), &statBuf);
  270.     if (statBuf.st_size) {
  271.     /* check ROM library file validity */
  272.     fread(&rom, ROM_LEN, 1, files[0]);
  273.     if (statBuf.st_size != ROM_LEN || rom.dir[0].adr != CHECK_ID) {
  274.         fprintf(stderr, "illegal ROM library file\n");
  275.         return (False);
  276.     }
  277.     } else {
  278.     /* create a new ROM library file */
  279.     printf("Creating a new library\n");
  280.     memset(rom.data, 0xff, ROM_LEN-sizeof(ROMDIR));
  281.     memset(rom.dir,  0x00, sizeof(ROMDIR));
  282.     }
  283.  
  284.     /* read linker outputfile to the ROM image buffer */
  285.     if ((words = loadLinkerToImage(files[1], True, BOOT_ADDRESS, BOOT_END)) != 0) {
  286.     updateDirEntry(&rom.dir[0], CHECK_ID, 0, comment, files[1]);
  287.     storeROM(files[0]);
  288.     } else
  289.     return (False);
  290.  
  291.     return (True);
  292. }
  293.  
  294.  
  295. Bool cdecl list(FILE *files[]) {
  296.     ROMDIR *p;
  297.     Bool    fEntryFound = False;
  298.     char    buf[11];
  299.  
  300.     if (!loadROMandCheckValidity(files[0]))
  301.     return (False);
  302.  
  303.     memcpy(buf, rom.dir[0].description, DESC_LEN); buf[DESC_LEN] = '\0';
  304.     printf("ROM: %-10s      %s\n", (*buf ? buf : "NO NAME"), dateStr(&rom.dir[0]));
  305.     for (p = &rom.dir[1]; p < &rom.dir[DIR_ENTRIES]; p++)
  306.     if (p->len) {
  307.         memcpy(buf, p->description, DESC_LEN); buf[DESC_LEN] = '\0';
  308.         printf("\n%2d%c  %-10s %4d %s", p-rom.dir, ((p-rom.dir) == rom.dir[0].len ? '*' : ' '), buf, p->len, dateStr(p));
  309.         fEntryFound = True;
  310.     }
  311.     if (!fEntryFound)
  312.     printf("\n     No programs found\n");
  313.  
  314.     return (True);
  315. }
  316.